/**
 */
package fUML.Semantics.Activities.IntermediateActivities;

import fUML.Semantics.Loci.LociL1.Locus;
import fUML.Semantics.Loci.LociL1.SemanticVisitor;

import fUML.Syntax.Activities.IntermediateActivities.ActivityNode;

import org.eclipse.emf.common.util.EList;

/**
 * <!-- begin-user-doc -->
 * A representation of the model object '<em><b>Activity Node Activation</b></em>'.
 * <!-- end-user-doc -->
 *
 * <!-- begin-model-doc -->
 * An activity node activation is used to define the behavior of an activity node
 *                 in the context of a containing activity or structured activity node.
 *               
 * <!-- end-model-doc -->
 *
 * <p>
 * The following features are supported:
 * <ul>
 *   <li>{@link fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation#getOutgoingEdges <em>Outgoing Edges</em>}</li>
 *   <li>{@link fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation#getIncomingEdges <em>Incoming Edges</em>}</li>
 *   <li>{@link fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation#getHeldTokens <em>Held Tokens</em>}</li>
 *   <li>{@link fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation#getGroup <em>Group</em>}</li>
 *   <li>{@link fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation#getNode <em>Node</em>}</li>
 *   <li>{@link fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation#isRunning <em>Running</em>}</li>
 * </ul>
 * </p>
 *
 * @see fUML.Semantics.Activities.IntermediateActivities.IntermediateActivitiesPackage#getActivityNodeActivation()
 * @model abstract="true"
 * @generated
 */
public interface ActivityNodeActivation extends SemanticVisitor {
	/**
	 * Returns the value of the '<em><b>Outgoing Edges</b></em>' reference list.
	 * The list contents are of type {@link fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstance}.
	 * It is bidirectional and its opposite is '{@link fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstance#getSource <em>Source</em>}'.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The set of activity edge instances for the outgoing edges of the node.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Outgoing Edges</em>' reference list.
	 * @see fUML.Semantics.Activities.IntermediateActivities.IntermediateActivitiesPackage#getActivityNodeActivation_OutgoingEdges()
	 * @see fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstance#getSource
	 * @model opposite="source" ordered="false"
	 * @generated
	 */
	EList<ActivityEdgeInstance> getOutgoingEdges();

	/**
	 * Returns the value of the '<em><b>Incoming Edges</b></em>' reference list.
	 * The list contents are of type {@link fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstance}.
	 * It is bidirectional and its opposite is '{@link fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstance#getTarget <em>Target</em>}'.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The set of activity edge instances for the incoming edges of the node.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Incoming Edges</em>' reference list.
	 * @see fUML.Semantics.Activities.IntermediateActivities.IntermediateActivitiesPackage#getActivityNodeActivation_IncomingEdges()
	 * @see fUML.Semantics.Activities.IntermediateActivities.ActivityEdgeInstance#getTarget
	 * @model opposite="target" ordered="false"
	 * @generated
	 */
	EList<ActivityEdgeInstance> getIncomingEdges();

	/**
	 * Returns the value of the '<em><b>Held Tokens</b></em>' containment reference list.
	 * The list contents are of type {@link fUML.Semantics.Activities.IntermediateActivities.Token}.
	 * It is bidirectional and its opposite is '{@link fUML.Semantics.Activities.IntermediateActivities.Token#getHolder <em>Holder</em>}'.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Held Tokens</em>' containment reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Held Tokens</em>' containment reference list.
	 * @see fUML.Semantics.Activities.IntermediateActivities.IntermediateActivitiesPackage#getActivityNodeActivation_HeldTokens()
	 * @see fUML.Semantics.Activities.IntermediateActivities.Token#getHolder
	 * @model opposite="holder" containment="true" ordered="false"
	 * @generated
	 */
	EList<Token> getHeldTokens();

	/**
	 * Returns the value of the '<em><b>Group</b></em>' container reference.
	 * It is bidirectional and its opposite is '{@link fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivationGroup#getNodeActivations <em>Node Activations</em>}'.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The group that contains this activity node activation.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Group</em>' container reference.
	 * @see #setGroup(ActivityNodeActivationGroup)
	 * @see fUML.Semantics.Activities.IntermediateActivities.IntermediateActivitiesPackage#getActivityNodeActivation_Group()
	 * @see fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivationGroup#getNodeActivations
	 * @model opposite="nodeActivations" required="true" transient="false" ordered="false"
	 * @generated
	 */
	ActivityNodeActivationGroup getGroup();

	/**
	 * Sets the value of the '{@link fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation#getGroup <em>Group</em>}' container reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Group</em>' container reference.
	 * @see #getGroup()
	 * @generated
	 */
	void setGroup(ActivityNodeActivationGroup value);

	/**
	 * Returns the value of the '<em><b>Node</b></em>' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The activity node being activated by this activity node activation. The node
	 *                   must be owned by the activity (type) of the activity execution of this node
	 *                   activation.
	 *  [This is optional, to allow for fork node edge queues and
	 *                   implicit fork and join node activations for actions to not have nodes in the
	 *                   model.]
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Node</em>' reference.
	 * @see #setNode(ActivityNode)
	 * @see fUML.Semantics.Activities.IntermediateActivities.IntermediateActivitiesPackage#getActivityNodeActivation_Node()
	 * @model ordered="false"
	 * @generated
	 */
	ActivityNode getNode();

	/**
	 * Sets the value of the '{@link fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation#getNode <em>Node</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Node</em>' reference.
	 * @see #getNode()
	 * @generated
	 */
	void setNode(ActivityNode value);

	/**
	 * Returns the value of the '<em><b>Running</b></em>' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * If true, this node activation is enabled for execution once all its other
	 *                   prerequesites are satisfied.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Running</em>' attribute.
	 * @see #setRunning(boolean)
	 * @see fUML.Semantics.Activities.IntermediateActivities.IntermediateActivitiesPackage#getActivityNodeActivation_Running()
	 * @model required="true" ordered="false"
	 * @generated
	 */
	boolean isRunning();

	/**
	 * Sets the value of the '{@link fUML.Semantics.Activities.IntermediateActivities.ActivityNodeActivation#isRunning <em>Running</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Running</em>' attribute.
	 * @see #isRunning()
	 * @generated
	 */
	void setRunning(boolean value);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Run the activation of this node.
	 *  
	 *  if (this.node != null)
	 *                   {
	 *  Debug.println("[run] node = " + this.node.name);
	 *  } else
	 *                   {
	 *  Debug.println("[run] Anonymous activation of type " +
	 *                   this.getClass().getName());
	 *  }
	 *  
	 *  this.running =
	 *                   true;
	 *  
	 * <!-- end-model-doc -->
	 * @model
	 * @generated
	 */
	void run();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Receive an offer from an incoming edge.
	 *  // Check if all
	 *                   prerequisites have been satisfied. If so, fire.
	 *  
	 *  if (this.node
	 *                   != null) {
	 *  Debug.println("[receiveOffer] node = " +
	 *                   this.node.name);
	 *  }
	 *  
	 *  _beginIsolation();
	 *                   
	 *  boolean ready = this.isReady();
	 *  
	 *  TokenList tokens =
	 *                   new TokenList();
	 *  if (ready) {
	 *  Debug.println("[receiveOffer]
	 *                   Firing.");
	 *  tokens = this.takeOfferedTokens();
	 *  }
	 *                   
	 *  _endIsolation();
	 *  
	 *  if (ready) {
	 *                   this.fire(tokens);
	 *  }
	 *  
	 *  
	 * <!-- end-model-doc -->
	 * @model
	 * @generated
	 */
	void receiveOffer();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Get tokens from all incoming edges.
	 *  
	 *  TokenList allTokens
	 *                   = new TokenList();
	 *  ActivityEdgeInstanceList incomingEdges =
	 *                   this.incomingEdges;
	 *  for (int i = 0; i < incomingEdges.size(); i++)
	 *                   {
	 *  ActivityEdgeInstance incomingEdge = incomingEdges.getValue(i);
	 *                   TokenList tokens = incomingEdge.takeOfferedTokens();
	 *  for (int j = 0; j
	 *                   < tokens.size(); j ++) {
	 *  Token token =
	 *                   tokens.getValue(j);
	 *  allTokens.addValue(token);
	 *  }
	 *                   }
	 *  
	 *  return allTokens;
	 *  
	 * <!-- end-model-doc -->
	 * @model ordered="false"
	 * @generated
	 */
	EList<Token> takeOfferedTokens();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * Carry out the main behavior of this activity node.
	 *  
	 * <!-- end-model-doc -->
	 * @model incomingTokensMany="true" incomingTokensOrdered="false"
	 * @generated
	 */
	void fire(EList<Token> incomingTokens);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @model tokensMany="true" tokensOrdered="false"
	 * @generated
	 */
	void sendOffers(EList<Token> tokens);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Terminate the activation of this node.
	 *  
	 *  if (this.running)
	 *                   {
	 *  if (this.node != null) {
	 *  Debug.println("[terminate] node = " +
	 *                   this.node.name);
	 *  } else {
	 *  Debug.println("[terminate] Anonymous
	 *                   activation of type " + this.getClass().getName());
	 *  }
	 *  }
	 *                   
	 *  this.running = false;
	 *  
	 * <!-- end-model-doc -->
	 * @model
	 * @generated
	 */
	void terminate();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Check if all the prerequisites for this node have been satisfied.
	 *                   // By default, check that this node is running.
	 *  
	 *  return
	 *                   this.isRunning();
	 *  
	 *  
	 * <!-- end-model-doc -->
	 * @model kind="operation" required="true" ordered="false"
	 * @generated
	 */
	boolean isReady();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Test whether this node activation is running.
	 *  
	 *  return
	 *                   this.running;
	 *  
	 * <!-- end-model-doc -->
	 * @model required="true" ordered="false"
	 * @generated
	 */
	boolean fUML_isRunning();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Add an activity edge instance as an outgoing edge of this activity node
	 *                   activation.
	 *  
	 *  edge.source = this;
	 *                   this.outgoingEdges.addValue(edge);
	 *  
	 * <!-- end-model-doc -->
	 * @model edgeRequired="true" edgeOrdered="false"
	 * @generated
	 */
	void addOutgoingEdge(ActivityEdgeInstance edge);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Add an activity edge instance as an incoming edge of this activity node
	 *                   activation.
	 *  
	 *  edge.target = this;
	 *                   this.incomingEdges.addValue(edge);
	 *  
	 * <!-- end-model-doc -->
	 * @model edgeRequired="true" edgeOrdered="false"
	 * @generated
	 */
	void addIncomingEdge(ActivityEdgeInstance edge);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Create node activations for any subnodes of the node for this
	 *                   activation.
	 *  // For most kinds of nodes, this does nothing.
	 *                   
	 *  return;
	 *  
	 *  
	 * <!-- end-model-doc -->
	 * @model
	 * @generated
	 */
	void createNodeActivations();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Create edge instances for any edge instances owned by the node for this
	 *                   activation.
	 *  // For most kinds of nodes, this does nothing.
	 *                   
	 *  return;
	 *  
	 *  
	 * <!-- end-model-doc -->
	 * @model
	 * @generated
	 */
	void createEdgeInstances();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Check if this node activation is the effective source for the given edge
	 *                   instance.
	 *  
	 *  return edgeInstance.source == this;
	 *  
	 * <!-- end-model-doc -->
	 * @model required="true" ordered="false" edgeInstanceRequired="true" edgeInstanceOrdered="false"
	 * @generated
	 */
	boolean isSourceFor(ActivityEdgeInstance edgeInstance);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Return the activity execution that contains this activity node activation,
	 *                   directly or indirectly.
	 *  
	 *  return
	 *                   this.group.getActivityExecution();
	 *  
	 * <!-- end-model-doc -->
	 * @model kind="operation" required="true" ordered="false"
	 * @generated
	 */
	ActivityExecution getActivityExecution();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Get the context object for the containing activity execution.
	 *                   
	 *  return this.getActivityExecution().context;
	 *  
	 * <!-- end-model-doc -->
	 * @model kind="operation" required="true" ordered="false"
	 * @generated
	 */
	fUML.Semantics.Classes.Kernel.Object getExecutionContext();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Get the locus of the containing activity execution.
	 *  
	 *                   return this.getActivityExecution().locus;
	 *  
	 * <!-- end-model-doc -->
	 * @model kind="operation" required="true" ordered="false"
	 * @generated
	 */
	Locus getExecutionLocus();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Get the activity node activation corresponding to the given activity node,
	 *                   in the context of this activity node activation.
	 *  // By default, return
	 *                   this activity node activation, if it is for the given node, otherwise return
	 *                   nothing.
	 *  
	 *  ActivityNodeActivation activation = null;
	 *  if
	 *                   (node == this.node) {
	 *  activation = this;
	 *  }
	 *  
	 *                   return activation;
	 * <!-- end-model-doc -->
	 * @model ordered="false" nodeRequired="true" nodeOrdered="false"
	 * @generated
	 */
	ActivityNodeActivation getNodeActivation(ActivityNode node);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @model tokenRequired="true" tokenOrdered="false"
	 * @generated
	 */
	void addToken(Token token);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Remove the given token, if it is held by this node activation.
	 *  //
	 *                   Return the position (counting from 1) of the removed token (0 if there is none
	 *                   removed).
	 *  
	 *  boolean notFound = true;
	 *  int i = 1;
	 *                   while (notFound & i <= this.heldTokens.size()) {
	 *  if
	 *                   (this.heldTokens.getValue(i-1) == token) {
	 *  if (this.node == null)
	 *                   {
	 *  Debug.println("[removeToken] ...");
	 *  } else {
	 *                   Debug.println("[removeToken] node = " + this.node.name);
	 *  }
	 *                   this.heldTokens.remove(i-1);
	 *  notFound = false;
	 *  }
	 *  i = i
	 *                   + 1;
	 *  }
	 *  
	 *  if (notFound) {
	 *  i = 0;
	 *  } else
	 *                   {
	 *  i = i - 1;
	 *  }
	 *  
	 *  return i ;
	 *  
	 * <!-- end-model-doc -->
	 * @model required="true" ordered="false" tokenRequired="true" tokenOrdered="false"
	 * @generated
	 */
	int removeToken(Token token);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Transfer the given tokens to be the held tokens for this node.
	 *                   
	 *  // if (this.node == null) {
	 *  // Debug.println("[addTokens]
	 *                   ...");
	 *  // } else {
	 *  // Debug.println("[addTokens] node = " +
	 *                   this.node.name);
	 *  // }
	 *  
	 *  for (int i = 0; i <
	 *                   tokens.size(); i++) {
	 *  Token token = tokens.getValue(i);
	 *                   this.addToken(token);
	 *  }
	 * <!-- end-model-doc -->
	 * @model tokensMany="true" tokensOrdered="false"
	 * @generated
	 */
	void addTokens(EList<Token> tokens);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Take the tokens held by this node activation.
	 *  
	 *  TokenList
	 *                   tokens = this.getTokens();
	 *  this.clearTokens();
	 *  
	 *  return
	 *                   tokens;
	 *  
	 * <!-- end-model-doc -->
	 * @model ordered="false"
	 * @generated
	 */
	EList<Token> takeTokens();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Remove all held tokens.
	 *  
	 *  while (this.heldTokens.size()
	 *                   > 0) {
	 *  this.heldTokens.getValue(0).withdraw();
	 *  }
	 *                   
	 *  
	 * <!-- end-model-doc -->
	 * @model
	 * @generated
	 */
	void clearTokens();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Get the tokens held by this node activation. 
	 *  
	 *  //
	 *                   Debug.println("[getTokens] node = " + this.node.name);
	 *  
	 *                   TokenList tokens = new TokenList();
	 *  TokenList heldTokens =
	 *                   this.heldTokens;
	 *  for (int i = 0; i < heldTokens.size(); i++)
	 *                   {
	 *  Token heldToken = heldTokens.getValue(i);
	 *  //
	 *                   Debug.println("[getTokens] token value = " + heldTokens.getValue());
	 *                   tokens.addValue(heldToken);
	 *  }
	 *  
	 *  return tokens;
	 *                 
	 * <!-- end-model-doc -->
	 * @model kind="operation" ordered="false"
	 * @generated
	 */
	EList<Token> getTokens();

} // ActivityNodeActivation
